package echo.demo1;

import echo.codec.MessageDecoder;
import echo.codec.MessageEncoder;
import echo.future.DefaultFuture;
import echo.protocol.MessageProtocol;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.util.CharsetUtil;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Client {
//    private static final Map<Integer, Object> FUTURES = new ConcurrentHashMap<>();
    private Channel channel;
    private ExecutorService executorService;
    //    public static void main(String[] args) throws InterruptedException {
//        NioEventLoopGroup group = new NioEventLoopGroup();
//        Bootstrap bootstrap = new Bootstrap();
//        bootstrap.group(group)
//                .channel(NioSocketChannel.class)
//                .handler(new ChannelInitializer<SocketChannel>() {
//                    @Override
//                    protected void initChannel(SocketChannel ch) throws Exception {
//                        ChannelPipeline pipeline = ch.pipeline();
//                        pipeline.addLast(new MessageEncoder());
//                        pipeline.addLast(new MessageDecoder());
//                        pipeline.addLast(new ClientHandler());
//                    }
//                });
//        ChannelFuture f = bootstrap.connect("localhost", 8000).sync();
//        Channel channel = f.channel();
//        for (int i = 0; i < 10; i++) {
//            String s = "asdsafdfdfdfdfdfdfdfdfdfd" + i + "   ";
//            MessageProtocol pro = new MessageProtocol();
//            byte[] bytes = s.getBytes(CharsetUtil.UTF_8);
//            pro.setLen(bytes.length);
//            pro.setContent(bytes);
//            ChannelFuture channelFuture = channel.writeAndFlush(pro);
//        }
//        f.channel().closeFuture().sync();
//    }


    public Client() throws InterruptedException {
        executorService = Executors.newFixedThreadPool(10);
        NioEventLoopGroup group = new NioEventLoopGroup();
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(group)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ChannelPipeline pipeline = ch.pipeline();
                        pipeline.addLast(new MessageEncoder());
                        pipeline.addLast(new MessageDecoder());
                        pipeline.addLast(new ClientHandler(executorService));
                    }
                });
        ChannelFuture f = bootstrap.connect("localhost", 8000).sync();
        Channel channel = f.channel();
        this.channel = channel;
//        f.channel().closeFuture();
    }

    /**
     * 目前仅支持String
     *
     */
    public DefaultFuture send(String msg) {
//        System.out.println(msg);
        MessageProtocol pro = new MessageProtocol();
        byte[] bytes = msg.getBytes(CharsetUtil.UTF_8);
        pro.setLen(bytes.length);
        pro.setContent(bytes);
        DefaultFuture future = new DefaultFuture(pro);
        ChannelFuture channelFuture = channel.writeAndFlush(pro);
        channelFuture.addListener((ChannelFutureListener) future1 -> {
            if (!future1.isSuccess()) {
//                    future.cause().printStackTrace();
            }
        });
        future.setReq(msg);
        return future;
    }
}
